﻿using EvEPriceData.EvECentralXml;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;
using T2Calc.Utilities;
using T2Calc.ViewObjects;
using T2CalcLib;
using T2CalcLib.Repositories;

namespace T2Calc.ViewModels
{
    public class MainWindowViewModel : BaseViewModel
    {
        #region Properties

        private Int32 me = -4;
        public Int32 ME 
        {
            get
            {
                return this.me;
            }
            set
            {
                this.me = value;
                this.notifyPropertyChanged();
            }
        }

        private Int32 runsPerBPC = 10;
        public Int32 RunsPerBPC
        {
            get
            {
                return this.runsPerBPC;
            }
            set
            {
                this.runsPerBPC = value;
                this.notifyPropertyChanged();
            }
        }

        private Decimal inventionChance = 0.4m;
        public Decimal InventionChance
        {
            get
            {
                return this.inventionChance;
            }
            set
            {
                this.inventionChance = value;
                this.notifyPropertyChanged();
            }
        }

        private Decimal sumCost;
        public Decimal SumCost
        {
            get
            {
                return this.sumCost;
            }
            set
            {
                this.sumCost = value;
                this.notifyPropertyChanged();
            }
        }

        private Decimal income;
        public Decimal Income
        {
            get
            {
                return this.income;
            }
            set
            {
                this.income = value;
                this.notifyPropertyChanged();
            }
        }

        private Decimal sumIncome;
        public Decimal SumIncome
        {
            get
            {
                return this.sumIncome;
            }
            set
            {
                this.sumIncome = value;
                this.notifyPropertyChanged();
            }
        }

        private Decimal profit;
        public Decimal Profit
        {
            get
            {
                return this.profit;
            }
            set
            {
                this.profit = value;
                this.notifyPropertyChanged();
            }
        }

        private Decimal sumProfit;
        public Decimal SumProfit
        {
            get
            {
                return this.sumProfit;
            }
            set
            {
                this.sumProfit = value;
                this.notifyPropertyChanged();
            }
        }

        private Int32 amountBPC = 1;
        public Int32 AmountBPC
        {
            get
            {
                return this.amountBPC;
            }
            set
            {
                this.amountBPC = value;
                this.notifyPropertyChanged();
            }
        }

        private Decimal percentProfit;
        public Decimal PercentProfit
        {
            get
            {
                return this.percentProfit;
            }
            set
            {
                this.percentProfit = value;
                this.notifyPropertyChanged();
            }
        }

        private T2ItemView selectedProduct;
        public T2ItemView SelectedProduct
        {
            get
            {
                if (this.selectedProduct == null
                    && this.Products != null
                    && this.Products.Count > 0)
                {
                    this.selectedProduct = this.Products.First();
                }
                return this.selectedProduct;
            }
            set
            {
                this.selectedProduct = value;
                this.notifyPropertyChanged();
            }
        }

        public List<T2ItemView> Products { get; set; }

        public ObservableCollection<MaterialView> InventionMats { get; set; }

        public ObservableCollection<MaterialView> ProductionMats { get; set; }

        #endregion

        public MainWindowViewModel()
        {
            this.Products = new List<T2ItemView>();
            this.InventionMats = new ObservableCollection<MaterialView>();
            this.ProductionMats = new ObservableCollection<MaterialView>();

            this.fillT2ItemsList();
        }

        #region Methods

        private void fillT2ItemsList()
        {
            this.Products.Clear();

            EvEDataRepository rep = new EvEDataRepository();

            foreach (var item in rep.GetT2Items().OrderBy(x => x.Item2))
            {
                this.Products.Add(new T2ItemView(item.Item1, item.Item2));
            }
        }

        public ICommand CalculateCommand
        {
            get 
            { 
                return new RelayCommand(parma => calculate()); 
            }
        }

        private void calculate()
        {
            if (this.SelectedProduct != null)
            {
                Calculation calculation = 
                    new Calculation(this.SelectedProduct.TypeID, 
                        this.ME, 
                        this.RunsPerBPC, 
                        this.InventionChance);

                this.InventionMats.Clear();

                foreach (var item in calculation.Invention.Datacores.OrderBy(x => x.TypeName))
                {
                    this.InventionMats.Add(new MaterialView(item.TypeID, 
                        item.TypeName, 
                        Math.Ceiling(item.Amount * this.AmountBPC * (1 / calculation.Invention.InventionChance)), 0, 0));
                }

                this.ProductionMats.Clear();

                foreach (var item in calculation.Production.MaterialsAndAmount.OrderBy(x => x.Key.TypeName))
                {
                    this.ProductionMats.Add(new MaterialView(item.Key.TypeID, 
                        item.Key.TypeName, 
                        item.Value * this.RunsPerBPC * this.AmountBPC, 0, 0));
                }

                foreach (var item in calculation.Production.MaterialExtras.OrderBy(x => x.TypeName))
                {
                    this.ProductionMats.Add(new MaterialView(item.TypeID, 
                        item.TypeName, 
                        item.Amount * this.RunsPerBPC * this.AmountBPC, 0, 0));
                }

                this.setPrice(calculation);
            }
            
        }

        private void setPrice(Calculation calculation)
        {
            List<Int64> typeIDs = new List<Int64>();

            typeIDs.Add(this.SelectedProduct.TypeID);
            typeIDs.AddRange(this.InventionMats.Select(x => x.TypeID));
            typeIDs.AddRange(this.ProductionMats.Select(x => x.TypeID));
            var data = EvecApi.Get(typeIDs);

            this.Income = data.Marketstat.Type.First(x => x.Id == this.SelectedProduct.TypeID).SellPricedata.Median;
            this.SumIncome = this.Income * this.RunsPerBPC * calculation.Production.AmountPerRun * this.amountBPC;

            Decimal sumCost = 0;
            foreach (var item in this.InventionMats)
            {
                item.Price = data.Marketstat.Type.First(x => x.Id == item.TypeID).SellPricedata.Median;
                item.Sum = item.Price * item.Amount;
                sumCost += item.Sum;
            }

            foreach (var item in this.ProductionMats)
            {
                item.Price = data.Marketstat.Type.First(x => x.Id == item.TypeID).SellPricedata.Median;
                item.Sum = item.Price * item.Amount;
                sumCost += item.Sum;
            }

            this.SumCost = sumCost;

            this.SumProfit = this.SumIncome - this.SumCost;
            this.Profit = this.SumProfit / this.RunsPerBPC / this.amountBPC / calculation.Production.AmountPerRun;
            this.PercentProfit = ((this.SumIncome / this.SumCost) - 1) * 100;
        }

        #endregion
    }
}
